package com.java2108.user.controller;


import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.java2108.user.entity.User;
import com.java2108.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.loadtime.Aj;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.geo.Point;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.bind.annotation.*;
import com.bw.zhanggm.common.*;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户信息表 前端控制器
 * </p>
 *
 * @author zhanggm
 * @since 2024-02-23
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    @Resource
//    @Qualifier("")
    private IUserService userService;

    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    RedissonClient redissonClient;

    //本地缓存
    private Map<String, Object> cacheMap = new HashMap<>();


    @GetMapping("page")
    public AjaxResult page(Page<User> page) {
        RLock lock = redissonClient.getLock("abc");
        if (!lock.tryLock()) {
            return AjaxResult.error();
        }
        lock.unlock();

        long current = page.getCurrent();
        if (current == 1) {
            final Object pageData = redisTemplate.opsForValue().get("user:pageData:"+current);
//            final Object pageData = cacheMap.get("user:pageData:" + current);
            if (pageData != null) {
                return AjaxResult.success(pageData);
            }
            Page<User> page1 = userService.page(page);
            redisTemplate.opsForValue().set("user:pageData:"+current, page1);
//            cacheMap.put("user:pageData:" + current, page1);
            return AjaxResult.success(page1);
        }
        return AjaxResult.success(userService.page(page));
    }


    @PostMapping("save")
    public AjaxResult save(@RequestBody User user) {
        //表单信息，要变成key，key变量
        String formJson = JSON.toJSON(user).toString();
        //为了解决formJson太大，占用redis的内容空间，用MD5做下签名
        String key = SecureUtil.md5(formJson);
        //表单重复提交
        /*if (!redisTemplate.opsForValue().setIfAbsent(key, null, 1, TimeUnit.SECONDS)) {
            return AjaxResult.error("表单重复提交了");
        }*/

//        if(redissonClient.getlo)

        userService.saveOrUpdate(user);
        //发送kafka消息
        String msg = JSON.toJSONString(user);
        kafkaTemplate.send("userMsg", UUID.randomUUID().toString(), msg);
        return AjaxResult.success();
    }


    @GetMapping("kafka")
    public AjaxResult kafka() {
        ListenableFuture send = kafkaTemplate.send("test", "key123", "data123");
        return AjaxResult.success();
    }

    //本地缓存
//    private final Map<String, Object> cacheMap = new HashMap<>();

    //修改数据库存字段就错的
    private int count = 0;


    @GetMapping("redisGeo")
    public synchronized AjaxResult redisGeo() {
        redisTemplate.opsForGeo().add("mygeo", new Point(116.397128, 39.916527), "Beijing");
        redisTemplate.opsForGeo().add("mygeo", new Point(121.472641, 31.231707), "Shanghai");
        redisTemplate.opsForGeo().add("mygeo", new Point(113.264435, 23.129163), "Guangzhou");

        double value = redisTemplate.opsForGeo().distance("mygeo", "Beijing", "Shanghai").getValue();
        System.out.println(value);

        return null;

    }


    @GetMapping("redis")
    public synchronized AjaxResult redis(String phone) {
        //统计
        count++;
        log.info("统计：{}", count);
        //缓存验证码
        String cacheKey = "code:" + phone;
//        if(redisTemplate.opsForValue().setIfAbsent())
        System.out.println();
        if (redisTemplate.hasKey(cacheKey)) {
            log.info("该手机已发送短信验证码");
            return AjaxResult.error();
        }
        RLock lock = redissonClient.getLock(cacheKey);
        try {
            if(lock.tryLock(10, TimeUnit.SECONDS)){
                //生成短信验证码
                int code = RandomUtil.randomInt(4);
                //cacheMap.put("code:" + phone, code+"");
                //发送短信
                log.info("手机号：{}，发送短信验证码：{}", phone, code);
                //缓存验证码
                redisTemplate.opsForValue().set(cacheKey, code, 10, TimeUnit.SECONDS);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return AjaxResult.success();
    }






}
